/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.app;

import android.app.Dialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.test.CustomPage;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.android.gallery3d.R;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.Path;
import com.android.gallery3d.picasasource.PicasaSource;
import com.android.gallery3d.util.GalleryUtils;

public final class GalleryActivity extends AbstractGalleryActivity implements
		OnCancelListener {
	public static final String EXTRA_SLIDESHOW = "slideshow";
	public static final String EXTRA_DREAM = "dream";
	public static final String EXTRA_CROP = "crop";

	public static final String ACTION_REVIEW = "com.android.camera.action.REVIEW";
	public static final String KEY_GET_CONTENT = "get-content";
	public static final String KEY_GET_ALBUM = "get-album";
	public static final String KEY_TYPE_BITS = "type-bits";
	public static final String KEY_MEDIA_TYPES = "mediaTypes";
	public static final String KEY_DISMISS_KEYGUARD = "dismiss-keyguard";

	private static final String TAG = "GalleryActivity";
	private Dialog mVersionCheckDialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_ACTION_BAR);
		requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

		if (getIntent().getBooleanExtra(KEY_DISMISS_KEYGUARD, false)) {
			// 解除锁屏，我们可以在setContentView之前加上这句，即可在启动这个activity的之前先解除锁屏
			getWindow().addFlags(
					WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
		}

		setContentView(R.layout.main);

		if (savedInstanceState != null) {
			getStateManager().restoreFromState(savedInstanceState);
		} else {
			initializeByIntent();
		}
	}

	private void initializeByIntent() {
		Intent intent = getIntent();
		String action = intent.getAction();

		if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)) {
			startGetContent(intent);
		} else if (Intent.ACTION_PICK.equalsIgnoreCase(action)) {
			// We do NOT really support the PICK intent. Handle it as
			// the GET_CONTENT. However, we need to translate the type
			// in the intent here.
			Log.w(TAG, "action PICK is not supported");
			String type = Utils.ensureNotNull(intent.getType());
			if (type.startsWith("vnd.android.cursor.dir/")) {
				if (type.endsWith("/image"))
					intent.setType("image/*");
				if (type.endsWith("/video"))
					intent.setType("video/*");
			}
			startGetContent(intent);
		} else if (Intent.ACTION_VIEW.equalsIgnoreCase(action)
				|| ACTION_REVIEW.equalsIgnoreCase(action)) {
			startViewAction(intent);
		} else {
			startDefaultPage();
		}
	}

	public void startDefaultPage() {
		PicasaSource.showSignInReminder(this);
		Bundle data = new Bundle();
		// getDataManager().getTopSetPath(DataManager.INCLUDE_ALL)

		// "/cluster/{/combo/{/local/all,/picasa/all}}/time";
		String basePath = getDataManager().getTopSetPath(
				DataManager.INCLUDE_LOCAL_DCIM_ONLY);

		String path = FilterUtils.switchClusterPath(basePath,
				FilterUtils.CLUSTER_BY_TIME);
		path = getDataManager().getTopSetPath(DataManager.INCLUDE_ALL);

//		data.putString(AlbumSetPage.KEY_MEDIA_PATH, path);
//		getStateManager().startState(AlbumSetPage.class, data);

		 data.putString(CustomPage.EXTRA_MEDIA_PATH, path);
		 getStateManager().startState(CustomPage.class, data);

		mVersionCheckDialog = PicasaSource.getVersionCheckDialog(this);
		if (mVersionCheckDialog != null) {
			mVersionCheckDialog.setOnCancelListener(this);
		}
	}

	private void startGetContent(Intent intent) {
		Log.d(TAG, "startGetContent");
		Bundle data = intent.getExtras() != null ? new Bundle(
				intent.getExtras()) : new Bundle();
		data.putBoolean(KEY_GET_CONTENT, true);
		int typeBits = GalleryUtils.determineTypeBits(this, intent);
		data.putInt(KEY_TYPE_BITS, typeBits);
		data.putString(AlbumSetPage.KEY_MEDIA_PATH, getDataManager()
				.getTopSetPath(typeBits));
		getStateManager().startState(AlbumSetPage.class, data);
	}

	private String getContentType(Intent intent) {
		Log.d(TAG, "getContentType");
		String type = intent.getType();
		if (type != null) {
			return GalleryUtils.MIME_TYPE_PANORAMA360.equals(type) ? MediaItem.MIME_TYPE_JPEG
					: type;
		}

		Uri uri = intent.getData();
		try {
			return getContentResolver().getType(uri);
		} catch (Throwable t) {
			Log.w(TAG, "get type fail", t);
			return null;
		}
	}

	private void startViewAction(Intent intent) {
		Log.d(TAG, "startViewAction");
		Boolean slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
		if (slideshow) {
			getActionBar().hide();
			DataManager manager = getDataManager();
			Path path = manager.findPathByUri(intent.getData(),
					intent.getType());
			if (path == null
					|| manager.getMediaObject(path) instanceof MediaItem) {
				path = Path.fromString(manager
						.getTopSetPath(DataManager.INCLUDE_IMAGE));
			}
			Bundle data = new Bundle();
			data.putString(SlideshowPage.KEY_SET_PATH, path.toString());
			data.putBoolean(SlideshowPage.KEY_RANDOM_ORDER, true);
			data.putBoolean(SlideshowPage.KEY_REPEAT, true);
			if (intent.getBooleanExtra(EXTRA_DREAM, false)) {
				data.putBoolean(SlideshowPage.KEY_DREAM, true);
			}
			getStateManager().startState(SlideshowPage.class, data);
		} else {
			Bundle data = new Bundle();
			DataManager dm = getDataManager();
			Uri uri = intent.getData();
			String contentType = getContentType(intent);
			if (contentType == null) {
				Toast.makeText(this, R.string.no_such_item, Toast.LENGTH_LONG)
						.show();
				finish();
				return;
			}
			if (uri == null) {
				int typeBits = GalleryUtils.determineTypeBits(this, intent);
				data.putInt(KEY_TYPE_BITS, typeBits);
				data.putString(AlbumSetPage.KEY_MEDIA_PATH, getDataManager()
						.getTopSetPath(typeBits));
				getStateManager().startState(AlbumSetPage.class, data);
			} else if (contentType
					.startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE)) {
				int mediaType = intent.getIntExtra(KEY_MEDIA_TYPES, 0);
				if (mediaType != 0) {
					uri = uri
							.buildUpon()
							.appendQueryParameter(KEY_MEDIA_TYPES,
									String.valueOf(mediaType)).build();
				}
				Path setPath = dm.findPathByUri(uri, null);
				MediaSet mediaSet = null;
				if (setPath != null) {
					mediaSet = (MediaSet) dm.getMediaObject(setPath);
				}
				if (mediaSet != null) {
					if (mediaSet.isLeafAlbum()) {
						data.putString(AlbumPage.KEY_MEDIA_PATH,
								setPath.toString());
						data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
								dm.getTopSetPath(DataManager.INCLUDE_ALL));
						getStateManager().startState(AlbumPage.class, data);
					} else {
						data.putString(AlbumSetPage.KEY_MEDIA_PATH,
								setPath.toString());
						getStateManager().startState(AlbumSetPage.class, data);
					}
				} else {
					startDefaultPage();
				}
			} else {
				Path itemPath = dm.findPathByUri(uri, contentType);
				Path albumPath = dm.getDefaultSetOf(itemPath);

				data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
						itemPath.toString());
				data.putBoolean(PhotoPage.KEY_READONLY, true);

				// TODO: Make the parameter "SingleItemOnly" public so other
				// activities can reference it.
				boolean singleItemOnly = (albumPath == null)
						|| intent.getBooleanExtra("SingleItemOnly", false);
				if (!singleItemOnly) {
					data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
							albumPath.toString());
					// when FLAG_ACTIVITY_NEW_TASK is set, (e.g. when intent is
					// fired
					// from notification), back button should behave the same as
					// up button
					// rather than taking users back to the home screen
					if (intent.getBooleanExtra(PhotoPage.KEY_TREAT_BACK_AS_UP,
							false)
							|| ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0)) {
						data.putBoolean(PhotoPage.KEY_TREAT_BACK_AS_UP, true);
					}
				}

				getStateManager().startState(SinglePhotoPage.class, data);
			}
		}
	}

	@Override
	protected void onResume() {
		Utils.assertTrue(getStateManager().getStateCount() > 0);
		super.onResume();
		if (mVersionCheckDialog != null) {
			mVersionCheckDialog.show();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mVersionCheckDialog != null) {
			mVersionCheckDialog.dismiss();
		}
	}

	@Override
	public void onCancel(DialogInterface dialog) {
		if (dialog == mVersionCheckDialog) {
			mVersionCheckDialog = null;
		}
	}

	@Override
	public boolean onGenericMotionEvent(MotionEvent event) {
		Log.d(TAG, "onGenericMotionEvent");
		final boolean isTouchPad = (event.getSource() & InputDevice.SOURCE_CLASS_POSITION) != 0;
		if (isTouchPad) {
			float maxX = event.getDevice().getMotionRange(MotionEvent.AXIS_X)
					.getMax();
			float maxY = event.getDevice().getMotionRange(MotionEvent.AXIS_Y)
					.getMax();
			View decor = getWindow().getDecorView();
			float scaleX = decor.getWidth() / maxX;
			float scaleY = decor.getHeight() / maxY;
			float x = event.getX() * scaleX;
			// x = decor.getWidth() - x; // invert x
			float y = event.getY() * scaleY;
			// y = decor.getHeight() - y; // invert y
			MotionEvent touchEvent = MotionEvent.obtain(event.getDownTime(),
					event.getEventTime(), event.getAction(), x, y,
					event.getMetaState());
			return dispatchTouchEvent(touchEvent);
		}
		return super.onGenericMotionEvent(event);
	}
}
